from typing import Optional, List
import uvicorn
from fastapi import FastAPI, Path, Query,Body
from fastapi.openapi.docs import get_swagger_ui_html
from pydantic import BaseModel,Field
from starlette.staticfiles import StaticFiles

# 创建 FastAPI 应用实例，并把默认的/docs请求禁用
# debug表示是否开启调试模式，默认是False
app = FastAPI(docs_url=None,debug=True)
app.mount("/static", StaticFiles(directory="../static"), name="static")    # 静态文件

@app.get("/docs", include_in_schema=False)
def custom_swagger_ui():
    return get_swagger_ui_html(
        openapi_url = "/openapi.json",
        title = "Swagger UI for FastAPI",
        swagger_js_url="/static/swagger-ui-bundle.min.js",
        swagger_css_url="/static/swagger-ui.min.css"
    )



class User(BaseModel):
    # ...表示它是一个必填项，
    username: str = Field(...,min_length=3)
    description: Optional[str] = Field(None,max_length=128)

class Item(BaseModel):
    name: str
    length: int

@app.put("/carts/{cart_id}")
async def update_cart(cart_id: int, user: User, item: Item):
    print(user.username)
    print(item.name)

    # 直接拼接两个dict
    result_dict = user.model_dump() | item.model_dump()

    return {"cart_id": cart_id, "result": result_dict}


@app.put("/orders/{order_id}")
# 我们把函数中的参数定义为Body参数，那么它就会变成请求体中的参数而不是查询参数
async def update_order(order_id: int, user: User, item: Item, count:int=Body(...,ge=10,le=1000)):
    print(user.username)
    print(item.name)
    print(count)
    return {"order_id": order_id, "result": {"username": user.username, "item_name": item.name, "count": count}}


class Address(BaseModel):
    province: str
    city: str
    region: str
    address: str

class School(BaseModel):
    name: str
    address: Address

@app.post("/schools")
async def create_school(school: School):
    school_dict = school.model_dump()
    print("school:", school_dict)
    address_dict = school.address.model_dump()
    print("address:", address_dict)
    return school_dict


class Student(BaseModel):
    name: str
    age: int
    # 这里我直接写list表示列表，但是这里有点缺点就是我们无法确定元素的类型
    # subjects: list
    # 使用这种方式我可以明确列表中元素的类型
    subjects: List[int]

@app.post("/students")
async def create_student(student: Student):
    student_dict = student.model_dump()
    print("student:", student_dict)
    return student_dict



if __name__ == '__main__':
    uvicorn.run("main:app", host="127.0.0.1", port=8005, reload=True)